﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace ProcessAnalysis
{
    public class SvgGraphs
    {
        private static string svgFileContent = string.Empty;
        private static string tempFileName = "SvgGraphs.html";

        const double height = 500.0;
        const int width = 1000;

        public String[] performancesNames;
        static string[] colors = new[] { "rgb(255, 0, 0)", "rgb(0, 255, 0)", "rgb(0, 0, 255)",
                                         "rgb(0, 255, 255)", "rgb(255, 0, 255)","rgb(255, 255, 0)",
                                         "rgb(100, 0, 0)", "rgb(0, 100, 0)", "rgb(0, 0, 100)",
                                         "rgb(100, 100, 0)", "rgb(0, 100, 100)", "rgb(100, 0, 100)",
                                         "rgb(180, 0, 0)", "rgb(0, 180, 0)", "rgb(0, 0, 180)",
                                         "rgb(180, 180, 0)", "rgb(0, 180, 180)", "rgb(180, 0, 180)",
                                         "rgb(30, 0, 0)", "rgb(0, 30, 0)", "rgb(0, 0, 30)",
                                         "rgb(30, 30, 0)", "rgb(0, 30, 30)", "rgb(30, 0, 30)"};

        public SvgGraphs(DataGridViewRow[] programsRows, Double[][][] performancesArray, RunningOptionsProperties graphsToShow)
        {
            svgFileContent = string.Empty;
            performancesNames = typeof(Performances).GetEnumNames();  

            for (int i = 0; i < performancesNames.Length; i++)
            {
                var isGraphExist =
                    graphsToShow.GetType().GetProperty(performancesNames[i].ToString().Replace("_", "")).GetValue(graphsToShow, null);

                if ((bool)isGraphExist)
                {

                    svgFileContent += "<html><body>";
                    svgFileContent += string.Format("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{0}\" height=\"{1}\" version=\"1.1\">",
                        width + 50, height + 100);

                    double[] maxPoints = new double[programsRows.Length];
                    for (int k = 0; k < programsRows.Length; k++)
                    {
                        maxPoints[k] = 1 + (int)performancesArray[i][programsRows[k].Index].Max();
                    }
                    double maxPoint = maxPoints.Max();
                    if (maxPoint < 1)
                    {
                        maxPoint = 1;
                    }
                    double shiftDown = 50;
                    double diffHeight = (double)height / (maxPoint + 2);
                    int shiftLeft = 70;

                    int[] numSeconds = new int[programsRows.Length];
                    for (int k = 0; k < programsRows.Length; k++)
                    {
                        numSeconds[k] = (int)performancesArray[i][programsRows[k].Index].Length;
                    }
                    int maxSeconds = numSeconds.Max();

                    int diffWidth = width / (maxSeconds + 1);

                    string name = performancesNames[i].ToString().Replace("_", " ");
                    svgFileContent += string.Format("<text x=\"0\" y=\"{0}\" fill=\"black\" font-size=\"33\">{1}</text>",30 , name);

                    for (int k = 0; k < programsRows.Length; k++)
                    {
                        svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"{2}\">{3}</text>",
                           width - 200, 30 + k * 15, colors[k], programsRows[k].Cells[0].Value);
                    }

                    double skip = 1.0;
                    if (maxPoint > 20)
                    {
                        skip = maxPoint / 20.0;
                        diffHeight = height / 22.0;
                    }

                    svgFileContent +=
                        string.Format("<line x1=\"{0}\" y1=\"{1}\" x2=\"{2}\" y2=\"{3}\" style=\"stroke:rgb(0,0,0);stroke-width:2\"/>"
                        , shiftLeft, 30 + height, width, 30 + height);
                    svgFileContent +=
                        string.Format("<line x1=\"{0}\" y1=\"{1}\" x2=\"{2}\" y2=\"{3}\" style=\"stroke:rgb(0,0,0);stroke-width:2\"/>"
                        , shiftLeft, 30 + shiftDown - 20, shiftLeft, 30 + height);

                    svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">Seconds</text>",
                        width - 30, 65 + height);

                    for (double k = 0; k < maxPoint + 1.0; k += skip)
                    {
                        switch (i)
                        {
                            case (int)Performances.Cpu_Consumption_Comparison:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2}%</text>",
                                    0, 30 + height - (diffHeight * (k / skip)), k);
                                break;
                            case (int)Performances.Private_Memory_Use:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2:n0} K</text>",
                                    0, 30 + height - (diffHeight * (k / skip)), k / 1024);
                                break;
                            case (int)Performances.Paging_Space:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2:n0} K</text>",
                                     0, 30 + height - (diffHeight * (k / skip)), k / 1024);
                                break;
                            case (int)Performances.Number_Of_Thread:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2:n0}</text>",
                                     0, 30 + height - (diffHeight * (k / skip)), k);
                                break;
                            case (int)Performances.Virtual_Memory_Size:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2:n0} K</text>",
                                    0, 30 + height - (diffHeight * (k / skip)), k / 1024);
                                break;
                            case (int)Performances.Phisical_Memory:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2:n0} K</text>",
                                    0, 30 + height - (diffHeight * (k / skip)), k / 1024);
                                break;
                            case (int)Performances.Modules_Loaded:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2:n0}</text>",
                                     0, 30 + height - (diffHeight * (k / skip)), k);
                                break;
                            case (int)Performances.Traffic_Received:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2:n0} K</text>",
                                    0, 30 + height - (diffHeight * (k / skip)), k / 1024);
                                break;
                            case (int)Performances.Traffic_Sent:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2:n0} K</text>",
                                    0, 30 + height - (diffHeight * (k / skip)), k / 1024);
                                break;
                            case (int)Performances.Compression_Ratio:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2}%</text>",
                                    0, 30 + height - (diffHeight * (k / skip)), k);
                                break;
                            case (int)Performances.DeCompression_Ratio:
                                svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2}%</text>",
                                    0, 30 + height - (diffHeight * (k / skip)), k);
                                break;
                        }
                    }

                    double step = 1;
                    int maxSecondsToShow = maxSeconds;
                    if (maxSecondsToShow > 30)
                    {
                        step = (double)maxSecondsToShow / 30.0;
                        maxSecondsToShow = 30;
                    }

                    int diffWidthSeconds = width / (maxSecondsToShow + 1);
                    for (int k = 0; k < maxSecondsToShow; k++)
                    {
                        svgFileContent += string.Format("<text x=\"{0}\" y=\"{1}\" fill=\"black\">{2}</text>",
                            shiftLeft + (k * diffWidthSeconds), 50.0 + height, k * step);
                    }

                    for (int k = 1; k < maxSeconds; k++)
                    {
                        for (int m = 0; m < programsRows.Length; m++)
                        {
                            int rowIndex = programsRows[m].Index;

                            double prevPoint = 0;
                            double nextPointPoint = 0;
                            if (k < performancesArray[i][rowIndex].Length)
                            {
                                prevPoint = performancesArray[i][rowIndex][k - 1];
                                nextPointPoint = performancesArray[i][rowIndex][k];
                            }
                            else if (k == performancesArray[i][rowIndex].Length)
                            {
                                prevPoint = performancesArray[i][rowIndex][k - 1];
                            }

                            svgFileContent += string.Format("<line x1 = \"{0}\" y1=\"{1}\" x2=\"{2}\" y2=\"{3}\"",
                            (k - 1) * diffWidth + shiftLeft, 30 + height - (prevPoint / skip) * diffHeight,
                            k * diffWidth + shiftLeft, 30 + height - (nextPointPoint / skip) * diffHeight);
                            svgFileContent += string.Format("style=\"stroke:{0};stroke-width:2\"/>", colors[m]); ;
                        }
                    }
                    svgFileContent += "</body></html>";
                }
            }
        }

        public void ShowGraphs() 
        {   
            if (string.IsNullOrEmpty(svgFileContent))
            {
                MessageBox.Show("There is a probelm with showing the graph");
            }
            else
            {
                File.WriteAllText(tempFileName, svgFileContent);
                var procc = System.Diagnostics.Process.Start(tempFileName);
            }
        }

        public void Delete()
        {
            if (File.Exists(tempFileName))
            {
                File.Delete(tempFileName);
            }
        }
    }
}
